package com.myBlog.controller;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.myBlog.config.ProjectConfigProperties;
import com.myBlog.pojo.WebsiteConfigRow;
import com.myBlog.repository.WebsiteConfigMapper;
import com.myBlog.utils.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Slf4j
@RestController
public class ConfigController {

    @Autowired
    private WebsiteConfigMapper configMapper;

    @Autowired
    RedisTemplate redisTemplate;
    // 网站配置的Redis的key
    private static String configRedisKey = "webSiteConfig";

    @Value("${webSite.config.save.prefix}")
    private String savePathPrefix;

    @Value("${webSite.config.visit.prefix}")
    private String visitPathPrefix;

    @Value("${myRedis.config.timeout}")
    private Integer redisTimeOut;

    @Autowired
    private ProjectConfigProperties properties;


    @PostMapping("/user/getConfig")
    public JSONObject getConfig(){
        WebsiteConfigRow configRow = (WebsiteConfigRow) redisTemplate.opsForValue().get(configRedisKey);
        if(configRow==null){
            WebsiteConfigRow dbConfigRow = configMapper.selectOne(null);
            log.info("重新查询 数据库网站配置项， 结果为 {}",dbConfigRow);
            if(dbConfigRow!=null){
                configRow = dbConfigRow;
                redisTemplate.opsForValue().set(configRedisKey, dbConfigRow);
            }
        }

        return JsonUtil.ok_with_Data(configRow==null?new HashMap<>(): configRow);
    }

    @PostMapping("/admin/setConfig")
    public JSONObject setConfig( @RequestParam(value = "name",required = false) String name, @RequestParam(value = "logo",required = false) MultipartFile logoFile,
                                 @RequestParam(value = "banner",required = false) MultipartFile bannerFile, @RequestParam(value = "background", required = false) MultipartFile backgroundFile) throws IOException {

        Objects.requireNonNull(name, "网站名称配置不得为空");

        // 1. 文件保存到本地
        String logoPath = this.saveConfigFile(logoFile);
        String bannerPath = this.saveConfigFile(bannerFile);
        String backgroundPath = this.saveConfigFile(backgroundFile);

        // 2. 更新数据库和redis
        WebsiteConfigRow configRowDB = configMapper.selectOne(null);
        WebsiteConfigRow websiteConfigRow = new WebsiteConfigRow();
        websiteConfigRow.setName( Objects.requireNonNullElse(name, configRowDB.getName()) );
        websiteConfigRow.setLogoPath( Objects.requireNonNullElse(logoPath, configRowDB.getLogoPath()) );
        websiteConfigRow.setBannerPath( Objects.requireNonNullElse(bannerPath, configRowDB.getBannerPath()) );
        websiteConfigRow.setBackgroundPath( Objects.requireNonNullElse(backgroundPath, configRowDB.getBackgroundPath()) );

        this.updateOrInsertConfig(websiteConfigRow);
        return JsonUtil.ok_info("设置成功");
    }

    @Transactional
    private void updateOrInsertConfig(WebsiteConfigRow configRow){
        Long count = configMapper.selectCount(null);
        if(count>0){
            configMapper.update(configRow, null);
        }else {
            configMapper.insert(configRow);
        }

        redisTemplate.opsForValue().set(configRedisKey, configRow, this.redisTimeOut, TimeUnit.MINUTES);
    }

    private String saveConfigFile(MultipartFile file) throws IOException {
        if(file==null){
            log.info("文件为null，不存在，跳过");
            return null; // 设置为null则代表设置不更新字段，使用旧值
        }
        if(file.getSize()==0){
            log.info("文件名 {} 的文件大小为0，跳过上传", file.getOriginalFilename());
            return null;
        }
        String dateStr = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        String newFileName =  String.join(properties.upload_file_dot , new String[]{ dateStr,String.valueOf((int) (Math.random()*1000)), file.getOriginalFilename() });
        new File(savePathPrefix).mkdirs();

        String filePath = savePathPrefix + '/' + newFileName;
        FileOutputStream fileOutputStream = new FileOutputStream(filePath);
        fileOutputStream.write(file.getBytes());

        fileOutputStream.flush();
        fileOutputStream.close();
        log.info("文件 {} 上传到路径 {} 成功, 新的名称为 {}",file.getOriginalFilename(), savePathPrefix, newFileName );
        return  visitPathPrefix+newFileName;
    }

}
